home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------- */
- /* COLRTRIX.C "Color Trix" */
- /* David Jarvis, 1987 Version 041787 */
- /* */
- /* Developed with Lattice C */
- /* */
- /* Contains and demonstrates the following functions for the Atari ST: */
- /* fade_to_black() Fades from the current palette to black */
- /* fade_from_black() Fades from black to the desired palette */
- /* gradually_change_colors() Causes a gradual palette change */
- /* flash_colors() Causes screen to 'flash' certain # of times */
- /* load_neo() Loads a NEOCHROME picture into a buffer */
- /* */
- /* These functions will work in any (current) ST resolution. This demo */
- /* is limited to low resolution because it uses NEOCHROME pictures to */
- /* illustrate the effects. */
- /* */
- /* Programmers may use any of these functions in their own programs */
- /* without incurring the slightest obligation, legal, moral or */
- /* otherwise. */
- /* -------------------------------------------------------------------- */
-
- #include <stdio.h> /* standard I/O definitions */
- #include <osbind.h> /* Operating system bindings */
- #include <fcntl.h> /* File control */
- #include <gemlib.h> /* VDI and AES definitions */
- #include <portab.h> /* Portable storage definitions */
-
- /* -------- keyboard definitions (scan codes) ------------------------- */
-
- #define HELP 0x00620000
- #define UNDO 0x00610000
- #define F01 0x003b0000
- #define F02 0x003c0000
- #define F03 0x003d0000
- #define F04 0x003e0000
- #define F05 0x003f0000
- #define F06 0x00400000
- #define F07 0x00410000
- #define F08 0x00420000
- #define F09 0x00430000
- #define F10 0x00440000
-
- /* ------- variable declarations ------------------------------------- */
-
- /* Form_alert() and v_gtext() strings */
- BYTE title[] = "[1][ COLRTRIX |-- David T. Jarvis, 1987 --][ OK ]";
- BYTE sorry[] =
- "[3][ Sorry ... | Use COLRTRIX in Low Resolution Only ][ @^!!?#* ]";
- BYTE err001[] = "[1][COLRTRIX Error 01:|Error opening File.][ OK ]";
- BYTE err002[] = "[1][COLRTRIX Error 02:|File was too small.][ OK ]";
- BYTE err999[] =
- "[1][COLRTRIX Error 99:|Unknown error in loading.][ OK ]";
- BYTE uprompt1[ 256 ], uprompt2[ 256 ];
-
- /* Character variables for file handling */
- BYTE filespec[65],
- currpath[65],
- filename[15];
-
- /* Pointer to base of screen buffer */
- BYTE *pbase;
- /* Picture buffers */
- BYTE buff1[ 32000 ], buff2[ 32000 ];
-
- /* GEM variables */
- WORD contrl[12], intin[128],
- ptsin[128], intout[128],
- ptsout[128], work_in[11],
- work_out[57], pxyarray[10],
- handle;
-
- /* Miscellanous variables */
- WORD pal1[ 16 ], pal2[ 16 ], oldpal[ 16 ], *curpal;
- LONG longch;
-
- /* ------ function declarations ----------------------------------- */
-
- BYTE *strcat(),
- *strcpy(),
- *fgets();
- WORD load_neo();
- void getpic();
- void work_init(), cls_without_mess(), clean_up(), help();
- void fade_to_black(), fade_from_black();
- void gradually_change_colors(), flash_colors(), screen_load();
-
- /* --------- Main program ------------------------------------------ */
-
- main()
- {
- WORD i, drive;
-
- /* Initialize the workstation */
- work_init();
-
- /* Obtain some information about the system */
- if (Getrez())
- {
- form_alert( 1,sorry );
- appl_exit();
- exit();
- }
- pbase = (BYTE *)Physbase();
- for (i=0; i<16; i++)
- oldpal[ i ] = Setcolor(i,-1);
-
- /* Initialize form_alert strings for prompting user */
- strcpy( uprompt1,"[1][ You will be prompted to |" );
- strcat( uprompt1, " Load NEO Picture 1. It |" );
- strcat( uprompt1, " will be used to |" );
- strcat( uprompt1, " demonstrate the graphics |" );
- strcat( uprompt1, " functions in COLRTRIX. ][ okay ]" );
- strcpy( uprompt2,"[1][ Now select NEO Picture 2.|" );
- strcat( uprompt2, " Only the Palette for it |" );
- strcat( uprompt2, " will be used -- it should|" );
- strcat( uprompt2, " differ from that of |" );
- strcat( uprompt2, " Picture 1. ][ okay ]" );
-
- /* Initialize filename,path and drive information */
- strcpy( currpath,"?:" );
- drive = Dgetdrv();
- currpath[0] = 'A'+drive;
- Dgetpath(&currpath[2],drive+1);
- strcat(currpath,"\\*.NEO");
-
- /* Clear the screen and get started */
- cls_without_mess();
- form_alert(1,title);
-
- /* Prompt for the first picture and load it */
- getpic( uprompt1,buff1,pal1,0 );
- curpal = (WORD *)pal1;
-
- /* Prompt for and load second picture */
- getpic( uprompt2,buff2,pal2,0 );
-
- /* Give instructions...then handle all subsequent input */
- help();
- Setpallete( pal1 );
- screen_load( buff1 );
- do {
- if (Bconstat(2))
- {
- longch = Bconin(2); /* use the LONG value to get scan codes */
- switch( longch )
- {
- case HELP: help();
- screen_load( buff1 );
- break;
- case UNDO: screen_load( buff1 );
- Setpallete( pal1 );
- curpal = (WORD *)pal1;
- break;
- case F01: fade_from_black( pal1,16,3 );
- curpal = (WORD *)pal1;
- break;
- case F02: fade_from_black( pal2,16,3 );
- curpal = (WORD *)pal2;
- break;
- case F03: fade_to_black( curpal,16,3 );
- break;
- case F04: if (curpal == pal1)
- {
- gradually_change_colors( pal1,pal2,16,3 );
- curpal = (WORD *)pal2;
- }
- else
- {
- gradually_change_colors( pal2,pal1,16,3 );
- curpal = (WORD *)pal1;
- }
- break;
- case F05: flash_colors( curpal,16,8,5 );
- break;
- case F06: getpic( uprompt1,buff1,pal1,1 );
- screen_load( buff1 );
- curpal = (WORD *)pal1;
- break;
- case F07: getpic( uprompt2,buff2,pal2,0 );
- screen_load( buff1 );
- break;
- case F08: graf_mouse( M_OFF,0L );
- for (i=0; i<32000; i++)
- buff1[ i ] = buff2[ i ];
- for (i=0; i<32000; i++)
- buff2[ i ] = pbase[ i ];
- graf_mouse( M_ON,0L );
- screen_load( buff1 );
- break;
- case F09: fade_from_black( pal1,16,16 );
- curpal = (WORD *)pal1;
- break;
- case F10: fade_to_black( curpal,16,2 );
- v_clrwk( handle );
- clean_up();
- exit();
- break;
- default: break;
- }
- } /* if Bconstat(2) */
- } while (1); /* for a very, very long time... */
- }
-
- /* -------- Additional functions ----------------------------------- */
-
- /* work_init() initializes the workstation */
- void work_init()
- {
- WORD i;
-
- appl_init();
- for( i = 0; i<10; work_in[ i++ ]=1 );
- work_in[10] = 2;
- v_opnvwk( work_in, &handle, work_out );
- }
-
- /* cls_without_mess() clears the screen without that nagging mouse block */
- void cls_without_mess()
- {
- graf_mouse(M_OFF,0L);
- v_clrwk( handle );
- graf_mouse(M_ON,0L);
- }
-
- /* clean_up() puts everything away before going home */
- void clean_up()
- {
- Setpallete( oldpal );
- appl_exit();
- }
-
- /* getpic() gets a NEO file...it prompts the user, calls load_neo(), */
- /* handles errors returned by that function */
- void getpic( prompt,where,pal,loadcolors )
- BYTE *prompt, *where;
- WORD *pal, loadcolors;
- {
- WORD err_ret, fs_exit;
- LONG i;
-
- /* Get the picture file name */
- form_alert(1,prompt);
- fsel_input(currpath,filename,&fs_exit);
- if (!fs_exit)
- {
- clean_up();
- exit();
- }
- else
- {
- strcpy(filespec,currpath);
- i = strlen(filespec)-1;
- while ( (i) && (filespec[ i ] != '\\') && (filespec[ i ] != ':'))
- i--;
- if (i)
- filespec[ i+1 ] = '\0';
- else
- filespec[ 0 ] = '\0';
- strcat(filespec,filename);
- graf_mouse(M_OFF,0L);
- err_ret = load_neo(filespec,where,pal,loadcolors);
- graf_mouse(M_ON,0L);
- switch(err_ret)
- {
- case 0: break;
- case -1: form_alert(1,err001);
- break;
- case -2: form_alert(1,err002);
- break;
- default: form_alert(1,err999);
- break;
- }
- }
- }
-
- /* ----------------------------------------------------------------- */
- /* load_neo() -- load a NEOCHROME picture file into memory */
- /* Type: */
- /* WORD -- Returns: 0 if successful */
- /* -- -1 if file could not be opened */
- /* -- -2 if file was too small (<32128 bytes) */
- /* Parameters: */
- /* filespec -- pointer to character string containing file name */
- /* where -- address of buffer to copy picture into */
- /* pal -- address of WORD array to copy pic's palette into */
- /* loadcolors -- 1 if screen colors should be changed to palette */
- /* ----------------------------------------------------------------- */
- WORD load_neo(filespec,where,pal,loadcolors)
- BYTE *filespec, *where;
- WORD *pal, loadcolors;
- {
- BYTE buffer[ 256 ];
- WORD nrez;
- LONG fhandle, ret;
-
- if ((fhandle = open(filespec,O_RDONLY | O_RAW)) < 0)
- return(-1);
- if ((ret = read(fhandle,&nrez,4L)) != 4L)
- return(-2);
- if ((ret = read(fhandle,pal,32L)) != 32L)
- return(-2);
- if ((ret = read(fhandle,buffer,92L)) != 92L)
- return(-2);
- if (loadcolors)
- Setpallete(pal);
- if ((ret = read(fhandle,where,32000L)) != 32000L)
- return(-2);
- close(fhandle);
- return(0);
- }
-
- /* screen_load() transfers the contents of a buffer onto the screen */
- /* Note that it uses the global variable pbase, which should point to */
- /* the base of screen memory */
- void screen_load( buffer )
- BYTE *buffer;
- {
- WORD i;
-
- graf_mouse( M_OFF,0L );
- for (i=0; i<32000; i++)
- pbase[ i ] = buffer[ i ];
- graf_mouse( M_ON,0L );
- }
-
- /* ----------------------------------------------------------------------- */
- /* Fade_to_black() gradually changes the indicated number of screen colors */
- /* to blackness */
- /* Parameters: */
- /* pal Pointer to 16 WORDs containing palette to start with */
- /* numcolors Changes only the first 'numcolors' colors */
- /* dfact Delay factor -- a value of 4 produces a smooth fade with */
- /* 16 colors; higher numbers produce a slower fade */
- /* ----------------------------------------------------------------------- */
- void fade_to_black( pal,numcolors,dfact )
- WORD pal[], numcolors, dfact;
- {
- WORD tempal[ 16 ];
- WORD i, done=1, place1, place2, place3;
- LONG j;
-
- /* Start with current palette */
- Setpallete( pal );
- for (i=0; i<16; i++)
- tempal[ i ] = pal[ i ];
-
- /* Gradually darken colors until all are black (000) */
- do
- {
- done = 1;
- for (i=0; i<numcolors; i++)
- {
- place1 = (WORD)(tempal[ i ]/256) * 256;
- place2 = (WORD)((tempal[ i ]-place1)/16) * 16;
- place3 = tempal[ i ] - (place1 + place2);
- if (place1 > 0)
- {
- tempal[ i ] -= 256;
- done = 0;
- }
- if (place2 > 0)
- {
- tempal[ i ] -= 16;
- done = 0;
- }
- if (place3 > 0)
- {
- tempal[ i ] --;
- done = 0;
- }
- /* delay for a few microseconds */
- for (j=0L; j<100L*dfact; j++)
- ;
- }
- /* At each change, install the new colors */
- if (!done)
- Setpallete( tempal );
- } while (!done);
- }
-
- /* ----------------------------------------------------------------------- */
- /* Fade_from_black() sets all colors to black, then gradually brightens */
- /* the indicated number of screen colors until they match the desired */
- /* palette */
- /* newpal Pointer to 16 WORDs containing desired color palette */
- /* numcolors Fades to only the first 'numcolors' colors */
- /* dfact Delay factor -- a value of 4 produces a smooth fade with */
- /* 16 colors; larger numbers produce slower fades */
- /* ----------------------------------------------------------------------- */
- void fade_from_black( newpal,numcolors,dfact )
- WORD newpal[], numcolors, dfact;
- {
- WORD tempal[ 16 ];
- WORD i, done=1, new1, new2, new3, temp1, temp2;
- LONG j;
-
- /* Start with the first numcolors completely black */
- for (i=0; i<16; i++)
- if (i<numcolors)
- tempal[ i ] = 0;
- else
- tempal[ i ] = newpal[ i ];
- Setpallete( tempal );
-
- /* Gradually brighten colors until all match appropriate values */
- do
- {
- done = 1;
- for (i=0; i<numcolors; i++)
- {
- new1 = (WORD)(newpal[ i ]/256) * 256;
- if (tempal[ i ] < new1)
- {
- tempal[ i ] += 256;
- done = 0;
- }
- temp1 = (WORD)(tempal[ i ]/256) * 256;
- new2 = (WORD)((newpal[ i ]-new1)/16) * 16;
- if (tempal[ i ]-temp1 < new2)
- {
- tempal[ i ] += 16;
- done = 0;
- temp2 = (WORD)((tempal[ i ]-temp1)/16) * 16;
- }
- temp2 = (WORD)((tempal[ i ]-temp1)/16) * 16;
- new3 = newpal[ i ] - (new1+new2);
- if (tempal[ i ]-(temp1+temp2) < new3)
- {
- tempal[ i ] ++;
- done = 0;
- }
- /* delay for a few microseconds */
- for (j=0L; j<100L*dfact; j++)
- ;
- }
- /* At each change, install the new colors */
- if (!done)
- Setpallete( tempal );
- } while (!done);
- Setpallete( newpal );
- }
-
- /* ----------------------------------------------------------------------- */
- /* Gradually_change_colors() fades from one palette to another */
- /* Parameters: */
- /* oldpal Pointer to 16 WORDs containing first color palette */
- /* newpal Pointer to 16 WORDs containing second color palette */
- /* numcolors Changes only the first 'numcolors' colors */
- /* dfact Delay factor -- a value of 4 produces a smooth change */
- /* with 16 colors; larger numbers produce slower change */
- /* ----------------------------------------------------------------------- */
- void gradually_change_colors( oldpal,newpal,numcolors,dfact )
- WORD oldpal[], newpal[], numcolors, dfact;
- {
- WORD tempal[ 16 ];
- WORD place1, place2, place3, oplace1, oplace2, oplace3;
- WORD i, done=1;
- LONG j;
-
- /* Start with palette 1 */
- Setpallete( oldpal );
- for (i=0; i<16; i++)
- tempal[ i ] = oldpal[ i ];
-
- /* Gradually alter temporary palette values until they match the new ones */
- do
- {
- done = 1;
- for (i=0; i<numcolors; i++)
- {
- place1 = (WORD)(newpal[ i ]/256) * 256;
- oplace1 = (WORD)(tempal[ i ]/256) * 256;
- place2 = (WORD)((newpal[ i ]-place1)/16) * 16;
- oplace2 = (WORD)((tempal[ i ]-oplace1)/16) * 16;
- place3 = newpal[ i ] - (place1+place2);
- oplace3 = tempal[ i ] - (oplace1+oplace2);
- if (oplace1 < place1)
- {
- tempal[ i ] += 256;
- done = 0;
- }
- else
- if (oplace1 > place1)
- {
- tempal[ i ] -= 256;
- done = 0;
- }
- if (oplace2 < place2)
- {
- tempal[ i ] += 16;
- done = 0;
- }
- else
- if (oplace2 > place2)
- {
- tempal[ i ] -= 16;
- done = 0;
- }
- if (oplace3 < place3)
- {
- tempal[ i ] ++;
- done = 0;
- }
- else
- if (oplace3 > place3)
- {
- tempal[ i ] --;
- done = 0;
- }
- /* delay for a few microseconds */
- for (j=0L; j<100L*dfact; j++)
- ;
- }
- /* At each change, install the new colors */
- if (!done)
- Setpallete( tempal );
- } while (!done);
- Setpallete( newpal );
- }
-
- /* ----------------------------------------------------------------------- */
- /* flash_colors() causes on-screen colors to briefly appear 'negative' */
- /* an indicated number of times. Useful for effects such as explosions... */
- /* Parameters: */
- /* pal Pointer to 16 WORDs containing palette values */
- /* numcolors Number of colors to change during flash operation */
- /* dfact Delay factor -- 8 or so produces quick flashes */
- /* times Number of times to flash */
- /* ----------------------------------------------------------------------- */
- void flash_colors( pal,numcolors,dfact,times )
- WORD pal[], numcolors, dfact, times;
- {
- WORD tempal[ 16 ];
- WORD i, place1, place2, place3;
- LONG j;
-
- /* Build palette of colors to 'flash' to */
- for (i=0; i<16; i++)
- if (i >= numcolors) /* If outside numcolors, use same color */
- tempal[ i ] = pal[ i ];
- else /* otherwise, use 'opposite' */
- {
- place1 = (WORD)(pal[ i ]/256) * 256;
- tempal[ i ] = (7*256-place1)*256;
- place2 = (WORD)((pal[ i ] - (place1*256))/16) * 16;
- tempal[ i ] += (7*16-place2)*16;
- place3 = pal[ i ] - ((place1*256) + (place2*16));
- tempal[ i ] += (7-place3);
- }
-
- /* Now, flash the user */
- for (i=0; i<times; i++)
- {
- Setpallete( tempal );
- for (j=0L; j<250L*dfact; j++)
- ;
- Setpallete( pal );
- for (j=0L; j<250L*dfact; j++)
- ;
- }
- }
-
- /* Help() displays instructions about COLRTRIX */
- void help()
- {
- graf_mouse( M_OFF,0L );
- v_clrwk( handle );
- v_gtext( handle,1,8*1, "Key COLRTRIX Commands" );
- v_gtext( handle,1,8*2, "---------------------------------------" );
- v_gtext( handle,1,8*3, "HELP Print These Instructions" );
- v_gtext( handle,1,8*4, "UNDO Display Picture 1, Palette 1" );
- v_gtext( handle,1,8*5, "F1 Fade In (to Palette 1)" );
- v_gtext( handle,1,8*6, "F2 Fade In (to Palette 2)" );
- v_gtext( handle,1,8*7, "F3 Fade Out" );
- v_gtext( handle,1,8*8, "F4 Gradual Palette Change" );
- v_gtext( handle,1,8*9, "F5 Color Flash" );
- v_gtext( handle,1,8*10,"F6 Re-Load Picture 1" );
- v_gtext( handle,1,8*11,"F7 Re-Load Picture 2" );
- v_gtext( handle,1,8*12,"F8 Switch Pictures" );
- v_gtext( handle,1,8*13,"F9 Slow Fade In (to Palette 1)" );
- v_gtext( handle,1,8*14,"F10 Exit" );
- v_gtext( handle,20,8*16,"Press any key to continue..." );
- getch();
- graf_mouse( M_ON,0L );
- }
-